WebAssemblyã®å€å€é¢æ°ã€ã³ã¿ãŒãã§ãŒã¹ãæ¢æ±ãããããã©ã®ããã«è€æ°æ»ãå€ã®åŠçãæé©åããããã©ãŒãã³ã¹ãšéçºè äœéšãåäžããããã解説ããŸãã
WebAssemblyå€å€é¢æ°ã€ã³ã¿ãŒãã§ãŒã¹ïŒè€æ°æ»ãå€ã®æé©å
WebAssemblyïŒWasmïŒã¯ãWebéçºãªã©ã«é©åœãããããããã©ãŠã¶ããã®ä»ã®ç°å¢ã§å®è¡ãããã¢ããªã±ãŒã·ã§ã³ã«ãã€ãã£ãã«è¿ãããã©ãŒãã³ã¹ãæäŸããŠããŸããWasmã®å¹çãšè¡šçŸåãé«ããéèŠãªæ©èœã®1ã€ããå€å€é¢æ°ã€ã³ã¿ãŒãã§ãŒã¹ã§ããããã«ããã颿°ã¯è€æ°ã®å€ãçŽæ¥è¿ãããšãã§ããåé¿çã®å¿ èŠæ§ããªãããã³ãŒãå®è¡å šäœãæ¹åããŸãããã®èšäºã§ã¯ãWebAssemblyã®å€å€é¢æ°ã€ã³ã¿ãŒãã§ãŒã¹ã®è©³çްãæãäžãããã®å©ç¹ãæ¢ããã³ãŒããæé©åããããã«ã©ã®ããã«äœ¿çšã§ãããã®å®çšçãªäŸãæäŸããŸãã
WebAssemblyå€å€é¢æ°ã€ã³ã¿ãŒãã§ãŒã¹ãšã¯äœãïŒ
åŸæ¥ãJavaScriptã®åæããŒãžã§ã³ãå«ãå€ãã®ããã°ã©ãã³ã°èšèªã®é¢æ°ã¯ãåäžã®å€ããè¿ããªããšããå¶éããããŸããããã®å¶çŽã«ãããéçºè ã¯ãªããžã§ã¯ããé åã䜿çšãããªã©ãè€æ°ã®ããŒã¿ãè¿ãããã«éæ¥çãªææ®µã«é ŒããããåŸãªãããšããããããŸããããããã®åé¿çã¯ãã¡ã¢ãªå²ãåœãŠãããŒã¿æäœã®ããã«ããã©ãŒãã³ã¹ã®ãªãŒããŒããããçºçãããŸãããWebAssemblyã§æšæºåãããå€å€é¢æ°ã€ã³ã¿ãŒãã§ãŒã¹ã¯ããã®å¶éã«çŽæ¥å¯ŸåŠããŸãã
å€å€æ©èœã«ãããWebAssembly颿°ã¯è€æ°ã®å€ãåæã«è¿ãããšãã§ããŸããããã«ãããã³ãŒããç°¡çŽ åãããã¡ã¢ãªå²ãåœãŠãåæžãããã³ã³ãã€ã©ãšä»®æ³ãã·ã³ããããã®å€ã®åŠçãæé©åã§ããããã«ãªããããããã©ãŒãã³ã¹ãåäžããŸããå€ãåäžã®ãªããžã§ã¯ããé åã«ããã±ãŒãžåãã代ããã«ã颿°ã¯ã·ã°ããã£ã§è€æ°ã®æ»ãå€ã®åã宣èšããã ãã§æžã¿ãŸãã
å€å€æ»ãå€ã®å©ç¹
ããã©ãŒãã³ã¹ã®æé©å
å€å€æ»ãå€ã®äž»ãªå©ç¹ã¯ããã©ãŒãã³ã¹ã§ããçµæãšãšã©ãŒã³ãŒãã®äž¡æ¹ãè¿ãå¿ èŠããã颿°ãèããŠã¿ãŸããããå€å€æ»ãå€ããªããã°ãäž¡æ¹ã®å€ãä¿æããããã«ãªããžã§ã¯ããé åãäœæãããããããŸãããããã«ã¯ããªããžã§ã¯ãã®ã¡ã¢ãªå²ãåœãŠããã®ããããã£ãžã®å€ã®ä»£å ¥ããããŠé¢æ°åŒã³åºãåŸã®ãããã®å€ã®ååŸãå¿ èŠã§ãããããã®ã¹ãããã¯ãã¹ãŠCPUãµã€ã¯ã«ãæ¶è²»ããŸããå€å€æ»ãå€ã䜿çšãããšãã³ã³ãã€ã©ã¯ãããã®å€ãã¬ãžã¹ã¿ãŸãã¯ã¹ã¿ãã¯äžã§çŽæ¥ç®¡çã§ããã¡ã¢ãªå²ãåœãŠã®ãªãŒããŒããããåé¿ã§ããŸããããã«ãããç¹ã«ããã©ãŒãã³ã¹ãéèŠãªã³ãŒãã»ã¯ã·ã§ã³ã§ãå®è¡æéãççž®ãããã¡ã¢ãªãããããªã³ããåæžãããŸãã
äŸïŒå€å€æ»ãå€ãªãïŒJavaScript颚ã®å ·äœäŸïŒ
function processData(input) {
// ... some processing logic ...
return { result: resultValue, error: errorCode };
}
const outcome = processData(data);
if (outcome.error) {
// Handle error
}
const result = outcome.result;
äŸïŒå€å€æ»ãå€ããïŒWebAssembly颚ã®å ·äœäŸïŒ
(func $processData (param $input i32) (result i32 i32)
;; ... äœããã®åŠçããžã㯠...
(return $resultValue $errorCode)
)
(local $result i32)
(local $error i32)
(call $processData $data)
(local.tee $error)
(local.set $result)
(if (local.get $error) (then ;; ãšã©ãŒãåŠç))
WebAssemblyã®äŸã§ã¯ã颿° $processData ã¯2ã€ã® i32 å€ãè¿ãããããã¯ããŒã«ã«å€æ° $result ãš $error ã«çŽæ¥ä»£å
¥ãããŸããäžéãªããžã§ã¯ãã®å²ãåœãŠã¯é¢äžããŠããããããã«ãã倧å¹
ã«å¹çãåäžããŸãã
ã³ãŒãã®å¯èªæ§ãšä¿å®æ§ã®åäž
å€å€æ»ãå€ã¯ãã³ãŒããããã¯ãªãŒã³ã§çè§£ããããããŸãããªããžã§ã¯ããé åããå€ãå±éããå¿ èŠããªããæ»ãå€ã¯é¢æ°ã·ã°ããã£ã§æç€ºçã«å®£èšããã倿°ã«çŽæ¥ä»£å ¥ã§ããŸããããã«ãããã³ãŒãã®æç¢ºããåäžãããšã©ãŒã®å¯èœæ§ãæžå°ããŸããéçºè ã¯ãå®è£ ã®è©³çްãæãäžããããšãªãã颿°ãäœãè¿ãããè¿ éã«ç¹å®ã§ããŸãã
äŸïŒæ¹åããããšã©ãŒãã³ããªã³ã°
å€ãšãšã©ãŒã³ãŒãããŸãã¯æå/倱æãã©ã°ã®äž¡æ¹ãè¿ãã®ã¯äžè¬çãªãã¿ãŒã³ã§ããå€å€æ»ãå€ã¯ããã®ãã¿ãŒã³ãã¯ããã«ãšã¬ã¬ã³ãã«ããŸããïŒé«äŸ¡ã«ãªããã¡ãªïŒäŸå€ãã¹ããŒããããã°ããŒãã«ãªãšã©ãŒç¶æ ã«äŸåããããã代ããã«ã颿°ã¯çµæãšãšã©ãŒã€ã³ãžã±ãŒã¿ãå¥åã®å€ãšããŠè¿ãããšãã§ããŸããåŒã³åºãå ã¯ããšã©ãŒã€ã³ãžã±ãŒã¿ãããã«ç¢ºèªããå¿ èŠãªãšã©ãŒæ¡ä»¶ãåŠçã§ããŸãã
ã³ã³ãã€ã©æé©åã®åŒ·å
ã³ã³ãã€ã©ã¯ãå€å€æ»ãå€ãæ±ãéã«ããåªããæé©åãå®è¡ã§ããŸãã颿°ãè€æ°ã®ç¬ç«ããå€ãè¿ãããšãç¥ã£ãŠãããšãã³ã³ãã€ã©ã¯ã¬ãžã¹ã¿ãããå¹ççã«å²ãåœãŠãåäžã®è€åæ»ãå€ã§ã¯äžå¯èœã ã£ãä»ã®æé©åãå®è¡ã§ããŸããã³ã³ãã€ã©ã¯ãæ»ãå€ãæ ŒçŽããããã®äžæçãªãªããžã§ã¯ããé åã®äœæãåé¿ã§ããããå¹ççãªã³ãŒãçæã«ã€ãªãããŸãã
çžäºéçšæ§ã®ç°¡çŽ å
å€å€æ»ãå€ã¯ãWebAssemblyãšä»ã®èšèªãšã®çžäºéçšæ§ãç°¡çŽ åããŸããããšãã°ãJavaScriptããWebAssembly颿°ãåŒã³åºãå Žåãå€å€æ»ãå€ã¯JavaScriptã®åå²ä»£å ¥æ©èœã«çŽæ¥ãããã³ã°ã§ããŸããããã«ãããéçºè ã¯è€éãªå±éã³ãŒããæžãããšãªããæ»ãå€ã«ç°¡åã«ã¢ã¯ã»ã¹ã§ããŸããåæ§ã«ãä»ã®èšèªãã€ã³ãã£ã³ã°ãå€å€æ»ãå€ã䜿çšããŠç°¡çŽ åã§ããŸãã
ãŠãŒã¹ã±ãŒã¹ãšäŸ
æ°åŠããã³ç©çã·ãã¥ã¬ãŒã·ã§ã³
å€ãã®æ°åŠããã³ç©çã·ãã¥ã¬ãŒã·ã§ã³ã«ã¯ãåœç¶è€æ°ã®å€ãè¿ã颿°ãå«ãŸããŸããããšãã°ã2ã€ã®ç·ã®äº€ç¹ãèšç®ãã颿°ã¯ã亀ç¹ã®x座æšãšy座æšãè¿ããããããŸãããé£ç«æ¹çšåŒãè§£ã颿°ã¯ãè€æ°ã®è§£ã®å€ãè¿ããããããŸãããå€å€æ»ãå€ã¯ãäžéããŒã¿æ§é ãäœæããããšãªãããã¹ãŠã®è§£ã®å€ãçŽæ¥è¿ãããšãã§ããããããããã®ã·ããªãªã«æé©ã§ãã
äŸïŒé£ç«äžæ¬¡æ¹çšåŒãè§£ã
2ã€ã®æªç¥æ°ãæã€2ã€ã®é£ç«äžæ¬¡æ¹çšåŒãè§£ãç°¡ç¥åãããäŸãèããŠã¿ãŸããããxãšyã®è§£ãè¿ã颿°ãæžãããšãã§ããŸãã
(func $solveLinearSystem (param $a i32 $b i32 $c i32 $d i32 $e i32 $f i32) (result i32 i32)
;; 次ã®é£ç«æ¹çšåŒãè§£ã:
;; a*x + b*y = c
;; d*x + e*y = f
;; (ç°¡ç¥åãããäŸããŒãé€ç®ã®ãšã©ãŒåŠçãªã)
(local $det i32)
(local $x i32)
(local $y i32)
(local.set $det (i32.sub (i32.mul (local.get $a) (local.get $e)) (i32.mul (local.get $b) (local.get $d))))
(local.set $x (i32.div_s (i32.sub (i32.mul (local.get $c) (local.get $e)) (i32.mul (local.get $b) (local.get $f))) (local.get $det)))
(local.set $y (i32.div_s (i32.sub (i32.mul (local.get $a) (local.get $f)) (i32.mul (local.get $c) (local.get $d))) (local.get $det)))
(return (local.get $x) (local.get $y))
)
ç»åããã³ä¿¡å·åŠç
ç»åããã³ä¿¡å·åŠçã¢ã«ãŽãªãºã ã«ã¯ãè€æ°ã®ã³ã³ããŒãã³ããçµ±èšãè¿ã颿°ãããå«ãŸããŸããããšãã°ãç»åã®ã«ã©ãŒãã¹ãã°ã©ã ãèšç®ãã颿°ã¯ãèµ€ãç·ãéã®ãã£ãã«ã®é »åºŠã«ãŠã³ããè¿ããããããŸãããããŒãªãšè§£æãå®è¡ãã颿°ã¯ã倿ã®å®æ°éšãšèæ°éšãè¿ããããããŸãããå€å€æ»ãå€ã«ããããããã®é¢æ°ã¯ãé¢é£ãããã¹ãŠã®ããŒã¿ãåäžã®ãªããžã§ã¯ããé åã«ããã±ãŒãžåããããšãªããå¹ççã«è¿ãããšãã§ããŸãã
ã²ãŒã éçº
ã²ãŒã éçºã§ã¯ã颿°ã¯ã²ãŒã ã®ç¶æ ãç©çããŸãã¯AIã«é¢é£ããè€æ°ã®å€ãé »ç¹ã«è¿ãå¿ èŠããããŸããããšãã°ã2ã€ã®ãªããžã§ã¯ãéã®è¡çªå¿çãèšç®ãã颿°ã¯ãäž¡æ¹ã®ãªããžã§ã¯ãã®æ°ããäœçœ®ãšé床ãè¿ããããããŸãããAIãšãŒãžã§ã³ãã®æé©ãªåããæ±ºå®ãã颿°ã¯ãå®è¡ããã¢ã¯ã·ã§ã³ãšä¿¡é ŒåºŠã¹ã³ã¢ãè¿ããããããŸãããå€å€æ»ãå€ã¯ããããã®æäœãåçåããããã©ãŒãã³ã¹ãåäžãããã³ãŒããç°¡çŽ åããã®ã«åœ¹ç«ã¡ãŸãã
äŸïŒç©çã·ãã¥ã¬ãŒã·ã§ã³ - è¡çªæ€åº
è¡çªæ€åºé¢æ°ã¯ãè¡çªãã2ã€ã®ãªããžã§ã¯ãã®æŽæ°ãããäœçœ®ãšé床ãè¿ããããããŸããã
(func $collideObjects (param $x1 f32 $y1 f32 $vx1 f32 $vy1 f32 $x2 f32 $y2 f32 $vx2 f32 $vy2 f32)
(result f32 f32 f32 f32 f32 f32 f32 f32)
;; ç°¡ç¥åãããè¡çªèšç®ïŒäŸã®ã¿ïŒ
(local $newX1 f32)
(local $newY1 f32)
(local $newVX1 f32)
(local $newVY1 f32)
(local $newX2 f32)
(local $newY2 f32)
(local $newVX2 f32)
(local $newVY2 f32)
;; ... ããã«è¡çªããžãã¯ãããŒã«ã«å€æ°ãæŽæ° ...
(return (local.get $newX1) (local.get $newY1) (local.get $newVX1) (local.get $newVY1)
(local.get $newX2) (local.get $newY2) (local.get $newVX2) (local.get $newVY2))
)
ããŒã¿ããŒã¹ãšããŒã¿åŠç
ããŒã¿ããŒã¹æäœãããŒã¿åŠçã¿ã¹ã¯ã§ã¯ã颿°ãè€æ°ã®æ å ±ãè¿ãå¿ èŠãããããšããããããŸããããšãã°ãããŒã¿ããŒã¹ããã¬ã³ãŒããååŸãã颿°ã¯ãã¬ã³ãŒãå ã®è€æ°ã®ãã£ãŒã«ãã®å€ãè¿ããããããŸãããããŒã¿ãéèšãã颿°ã¯ãåèšãå¹³åãæšæºåå·®ãªã©ã®è€æ°ã®èŠçŽçµ±èšãè¿ããããããŸãããå€å€æ»ãå€ã¯ãçµæãä¿æããããã®äžæçãªããŒã¿æ§é ãäœæããå¿ èŠããªããããšã§ããããã®æäœãç°¡çŽ åããããã©ãŒãã³ã¹ãåäžãããããšãã§ããŸãã
å®è£ ã®è©³çް
WebAssemblyããã¹ã圢åŒïŒWATïŒ
WebAssemblyããã¹ã圢åŒïŒWATïŒã§ã¯ãå€å€æ»ãå€ã¯é¢æ°ã·ã°ããã£å
ã§ (result ...) ããŒã¯ãŒããšæ»ãå€ã®åã®ãªã¹ãã䜿çšããŠå®£èšãããŸããããšãã°ã2ã€ã®32ãããæŽæ°ãè¿ã颿°ã¯æ¬¡ã®ããã«å®£èšãããŸãïŒ
(func $myFunction (param $input i32) (result i32 i32)
;; ... 颿°ã®æ¬äœ ...
)
è€æ°ã®æ»ãå€ãæã€é¢æ°ãåŒã³åºãå ŽåãåŒã³åºãå
ã¯çµæãæ ŒçŽããããã®ããŒã«ã«å€æ°ãå²ãåœãŠãå¿
èŠããããŸããcall åœä»€ã¯ããããã®ããŒã«ã«å€æ°ã«ã颿°ã·ã°ããã£ã§å®£èšãããé åºã§æ»ãå€ãèšå®ããŸãã
JavaScript API
JavaScriptããWebAssemblyã¢ãžã¥ãŒã«ãšå¯Ÿè©±ããå Žåãå€å€æ»ãå€ã¯èªåçã«JavaScriptã®é åã«å€æãããŸããéçºè ã¯ãé åã®åå²ä»£å ¥ã䜿çšããŠãåã ã®æ»ãå€ã«ç°¡åã«ã¢ã¯ã»ã¹ã§ããŸãã
const wasmModule = await WebAssembly.instantiateStreaming(fetch('module.wasm'));
const { myFunction } = wasmModule.instance.exports;
const [result1, result2] = myFunction(input);
console.log(result1, result2);
ã³ã³ãã€ã©ã®ãµããŒã
EmscriptenãRustãAssemblyScriptãªã©ãWebAssemblyãã¿ãŒã²ãããšããã»ãšãã©ã®ææ°ã®ã³ã³ãã€ã©ã¯ãå€å€æ»ãå€ããµããŒãããŠããŸãããããã®ã³ã³ãã€ã©ã¯ãå€å€æ»ãå€ãåŠçããããã«å¿ èŠãªWebAssemblyã³ãŒããèªåçã«çæãããããéçºè ã¯äœã¬ãã«ã®WebAssemblyã³ãŒããçŽæ¥èšè¿°ããããšãªãããã®æ©èœãå©çšã§ããŸãã
å€å€æ»ãå€ã䜿çšããããã®ãã¹ããã©ã¯ãã£ã¹
- é©åãªå Žåã«å€å€æ»ãå€ã䜿çšããïŒ ãã¹ãŠãç¡çã«å€å€æ»ãå€ã«ããã®ã§ã¯ãªãã颿°ãèªç¶ã«è€æ°ã®ç¬ç«ããå€ãçæããå Žåã«æ€èšããŠãã ããã
- æ»ãå€ã®åãæç¢ºã«å®çŸ©ããïŒ ã³ãŒãã®å¯èªæ§ãšä¿å®æ§ãåäžãããããã«ãåžžã«é¢æ°ã·ã°ããã£ã§æ»ãå€ã®åãæç€ºçã«å®£èšããŠãã ããã
- ãšã©ãŒãã³ããªã³ã°ãèæ ®ããïŒ çµæãšãšã©ãŒã³ãŒããŸãã¯ã¹ããŒã¿ã¹ã€ã³ãžã±ãŒã¿ã®äž¡æ¹ãå¹ççã«è¿ãããã«ãå€å€æ»ãå€ã䜿çšããŠãã ããã
- ããã©ãŒãã³ã¹ã®ããã«æé©åããïŒ ã³ãŒãã®ããã©ãŒãã³ã¹ãéèŠãªã»ã¯ã·ã§ã³ã§å€å€æ»ãå€ã䜿çšããã¡ã¢ãªå²ãåœãŠãåæžããå®è¡é床ãåäžãããŠãã ããã
- ã³ãŒããææžåããïŒ ä»ã®éçºè ãã³ãŒããçè§£ãã䜿çšããããããããã«ãåæ»ãå€ã®æå³ãæç¢ºã«ææžåããŠãã ããã
å¶éãšèæ ®äºé
å€å€æ»ãå€ã¯å€§ããªå©ç¹ãæäŸããŸãããçæãã¹ãããã€ãã®å¶éãšèæ ®äºé ããããŸãïŒ
- ãããã°ïŒ ãããã°ãããå°é£ã«ãªãå¯èœæ§ããããŸããããŒã«ã¯ãè€æ°ã®æ»ãå€ãé©åã«è¡šç€ºããåŠçããå¿ èŠããããŸãã
- ããŒãžã§ã³ã®äºææ§ïŒ 䜿çšããŠããWebAssemblyã©ã³ã¿ã€ã ãšããŒã«ãå€å€æ©èœãå®å šã«ãµããŒãããŠããããšã確èªããŠãã ãããå€ãã©ã³ã¿ã€ã ã¯ãµããŒãããŠããªãå Žåããããäºææ§ã®åé¡ã«ã€ãªããå¯èœæ§ããããŸãã
WebAssemblyãšå€å€æ»ãå€ã®æªæ¥
å€å€é¢æ°ã€ã³ã¿ãŒãã§ãŒã¹ã¯ãWebAssemblyã®é²åã«ãããéèŠãªã¹ãããã§ããWebAssemblyãæçãç¶ããããåºãæ¡çšãããã«ã€ããŠãå€å€æ»ãå€ã®åŠçã«ããããããªãæ¹åãšæé©åãæåŸ ã§ããŸããå°æ¥ã®éçºã«ã¯ãããæŽç·Žãããã³ã³ãã€ã©æé©åãããè¯ããããã°ããŒã«ãããã³ä»ã®ããã°ã©ãã³ã°èšèªãšã®çµ±å匷åãå«ãŸããå¯èœæ§ããããŸãã
WebAssemblyã¯å¢çãæŒãåºãç¶ããŠããŸãããšã³ã·ã¹ãã ãæçããã«ã€ããŠãéçºè ã¯ããå€ãã®ããŒã«ãããè¯ãã³ã³ãã€ã©æé©åãããã³ä»ã®ãšã³ã·ã¹ãã ïŒNode.jsããµãŒããŒã¬ã¹ãã©ãããã©ãŒã ãªã©ïŒãšã®ããæ·±ãçµ±åãå©çšã§ããããã«ãªããŸããããã¯ãå€å€æ»ãå€ãä»ã®é«åºŠãªWebAssemblyæ©èœãããã«åºãæ¡çšãããããšãæå³ããŸãã
çµè«
WebAssemblyã®å€å€é¢æ°ã€ã³ã¿ãŒãã§ãŒã¹ã¯ãéçºè ãããå¹ççã§ãèªã¿ããããä¿å®ããããã³ãŒããæžãããšãå¯èœã«ãã匷åãªæ©èœã§ãã颿°ãè€æ°ã®å€ãçŽæ¥è¿ãããšãèš±å¯ããããšã«ãããåé¿çã®å¿ èŠæ§ããªãããå šäœçãªããã©ãŒãã³ã¹ãåäžãããŸããWebã¢ããªã±ãŒã·ã§ã³ãã²ãŒã ãã·ãã¥ã¬ãŒã·ã§ã³ããŸãã¯ãã®ä»ã®çš®é¡ã®ãœãããŠã§ã¢ãéçºããŠããå Žåã§ããã³ãŒããæé©åããWebAssemblyã®èœåãæå€§éã«æŽ»çšããããã«å€å€æ»ãå€ã®äœ¿çšãæ€èšããŠãã ãããé©åãªé©çšã¯ãã¢ããªã±ãŒã·ã§ã³ã®å¹çãšè¡šçŸåãåçã«åäžããããããäžçäžã®ãšã³ããŠãŒã¶ãŒã«ãããéããããå¿çæ§ã®é«ãäœéšãæäŸããããšã«ã€ãªãããŸãã